<script>
    let activeEffect
    class Dep {
        subscribers = new Set()
        depend() {
            if(activeEffect) {
                this.subscribers.add(activeEffect)
            }
        }

        notify() {
            this.subscribers.forEach(effect => {
                effect()
            })
        }
    }

    function watchEffect (effect) {
        activeEffect = effect
        effect()
        activeEffect = null
    }

    const targetsMap = new WeakMap()
    
    function getDep(target, key) {
        let depsMap = targetsMap.get(target)
        if(!depsMap) {
            depsMap = new Map()
            targetsMap.set(target, depsMap)
        }
        let dep = depsMap.get(key)
        if(!dep){
            dep = new Dep()
            depsMap.set(key, dep)
        }
        return dep
    }

    let reactiveHandlers = {
        get(target, key, receiver) {
            let dep = getDep(target, key)
            dep.depend()
            return Reflect.get(target, key, receiver)
        },
        set(target, key, value, receiver) {
            let dep = getDep(target, key)
            let result = Reflect.set(target, key, value, receiver)
            dep.notify()
            return result
        }
    }
    function reactive(raw) {
        return new Proxy(raw, reactiveHandlers)
    }


    const state = reactive({
        count: 0
    })

    watchEffect(() => {
        console.log(state.count, '----')
    })

    state.count++
</script>